/** render table cell */
import { h } from "vue";
import dayjs from "dayjs";

// simple cache to store parsed symbol parts
const symbolCellPartsCache = new Map<
  string,
  Array<{ text: string; isNumber: boolean }>
>();

/**
 * Format a number as plain text with optional thousand separators and fixed digits.
 * Returns an empty string for non-finite values so callers can provide their own fallback.
 */
export function formatNumberText(
  value?: number | null,
  options?: { digits?: number; separated?: boolean; isWan?: boolean }
): string {
  const digits = options?.digits ?? 2;
  const separated = options?.separated ?? true;
  const isWan = options?.isWan ?? false;

  if (typeof value !== "number" || !Number.isFinite(value)) return "";

  let workingValue = value;
  let suffix = "";
  if (isWan || workingValue >= 10000000) {
    workingValue = workingValue / 10000;
    suffix = "万";
  }

  const fixed = Number(workingValue).toFixed(digits);
  const formatted = separated
    ? Number(fixed).toLocaleString("en-US", {
        minimumFractionDigits: digits,
        maximumFractionDigits: digits
      })
    : fixed;

  return `${formatted}${suffix}`;
}

export const renderNumberCell = (
  value: number,
  digits: number = 0,
  separated: boolean = false,
  colored: boolean = false,
  isWan: boolean = false,
  className: string = ""
) => {
  const presetClassName = [
    "decimal-align",
    "font-mono",
    "font-medium",
    "text-xs sm:text-sm md:text-[15px]",
    className
  ];
  if (!Number.isFinite(value)) {
    return h("span", { class: presetClassName.filter(Boolean).join(" ") }, "");
  }
  const formattedText = formatNumberText(value, {
    digits,
    separated,
    isWan
  });
  let colorClass = "";
  if (colored && Number.isFinite(value)) {
    colorClass = value <= 0 ? "text-text_green_text" : "text-text_red_text";
  }

  const classes = [...presetClassName, colorClass].filter(Boolean).join(" ");

  return h("span", { class: classes }, formattedText);
};

export const renderTextCell = (
  text: string | number,
  className: string = ""
) => {
  const baseClassName = ["text-[11px]", "sm:text-xs", "md:text-sm", className]
    .filter(Boolean)
    .join(" ");

  const content =
    text === null ||
    text === undefined ||
    (typeof text === "string" && text.length === 0)
      ? ""
      : String(text);

  return h("span", { class: baseClassName }, content);
};

export const renderSymbolCell = (symbol: string) => {
  let cached = symbolCellPartsCache.get(symbol);
  if (!cached) {
    cached = symbol
      .split(/(\d+)/)
      .map(part => ({ text: part, isNumber: /^\d+$/.test(part) }));
    symbolCellPartsCache.set(symbol, cached);
  }

  const children = cached.map(({ text, isNumber }) =>
    h(
      "span",
      {
        class: isNumber ? "font-mono" : "font-mono font-bold text-gray-800"
      },
      text
    )
  );

  return h("span", { class: "text-[11px] sm:text-xs md:text-sm" }, children);
};

export const renderDatetimeCell = (
  value: string | number | Date | null | undefined,
  format: string = "YYYY-MM-DD HH:mm:ss",
  className: string = ""
) => {
  const baseClassName = [
    "text-[11px]",
    "sm:text-xs",
    "md:text-sm",
    "font-mono",
    className
  ]
    .filter(Boolean)
    .join(" ");

  if (!value) return h("span", { class: baseClassName }, "-");
  const ts = dayjs(value);
  const text = ts.isValid() ? ts.format(format) : "-";
  return h("span", { class: baseClassName }, text);
};
